using System;
using System.Threading;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;

namespace AvaloniaWeChatList.Extensions;

public sealed class TemplatedControlExtension : AvaloniaObject
{
    private const string Changed = ":changed";
    private const string BordyPressedPseudoClasses = ":pressed";
    private const string RightButtonPressedPseudoClasses = ":rightButtonPressed";

    private static ScrollViewer? _scrollViewer;

    private static readonly Timer ScrollViewerCloseChangedClassesTimer =
        new Timer(OnClosedClassesCallback, null, Timeout.Infinite, Timeout.Infinite);

    static TemplatedControlExtension()
    {
        ScrollViewer.ScrollChangedEvent.AddClassHandler<ScrollViewer>(OnScrollViewerChanged,
            handledEventsToo: true);
        InputElement.PointerPressedEvent.AddClassHandler<ListBoxItem>(OnPointerPressed,
            handledEventsToo: true);
    }

    /// <summary>
    /// 当listboxitem被按下时触发事件
    /// </summary>
    /// <param name="listBoxItem"></param>
    /// <param name="arg2"></param>
    private static void OnPointerPressed(ListBoxItem listBoxItem, PointerEventArgs arg2)
    {
        var pointerPoint = arg2.GetCurrentPoint(listBoxItem);

        if (listBoxItem.Classes is not IPseudoClasses pseudo)
            return;

        if (listBoxItem.ContextFlyout is not MenuFlyout flyout)
            return;

        flyout.Closed += OnClosed;

        pseudo.Set(RightButtonPressedPseudoClasses, pointerPoint.Properties.IsRightButtonPressed);
    }

    /// <summary>
    /// 当菜单按钮关闭的时候设置RightButtonPressedPseudoClasses为false
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void OnClosed(object? sender, EventArgs e)
    {
        if (sender is not MenuFlyout flyout)
            return;

        flyout.Closed -= OnClosed;

        if (flyout.Target is not ListBoxItem listBoxItem)
            return;

        if (listBoxItem.Classes is not IPseudoClasses pseudo)
            return;

        pseudo.Set(RightButtonPressedPseudoClasses, false);
    }

    /// <summary>
    /// 关闭
    /// </summary>
    /// <param name="state"></param>
    private static void OnClosedClassesCallback(object? state)
    {
        try
        {
            ScrollViewerCloseChangedClassesTimer.Change(Timeout.Infinite, Timeout.Infinite);

            if (_scrollViewer?.Classes is not IPseudoClasses pseudo)
                return;

            Avalonia.Threading.Dispatcher.UIThread.Invoke(() => pseudo.Set(Changed, false));
        }
        finally
        {
            ScrollViewerCloseChangedClassesTimer.Change(Timeout.Infinite, Timeout.Infinite);
        }
    }

    /// <summary>
    /// 滚动条滚动时候
    /// </summary>
    /// <param name="scrollViewer"></param>
    /// <param name="arg2"></param>
    private static void OnScrollViewerChanged(ScrollViewer scrollViewer,
        ScrollChangedEventArgs arg2)
    {
        if (scrollViewer.Classes is not IPseudoClasses pseudo)
            return;

        _scrollViewer ??= scrollViewer;

        pseudo.Set(Changed, true);

        //等待3秒之后触发关闭 Changed伪类
        ScrollViewerCloseChangedClassesTimer.Change(3000, 3000);
    }

    public static void Init()
    {
    }
}